package socketVersion.Middle;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Scanner;
import java.util.Vector;

import socketVersion.Reply;
import socketVersion.Request;
import socketVersion.GenericServer;
import socketVersion.GenericClient;

public class MiddleLayer extends GenericServer{
	
	private String CUSTOMER_SERVER = "customerServer";
	private String ROOM_SERVER = "roomServer";
	private String CAR_SERVER = "carServer";
	private String FLIGHT_SERVER = "flightServer";
	private Map<String,String> serverResponsibilities;
	
	private GenericClient customerServerWrapper;
	private GenericClient carServerWrapper;
	private GenericClient flightServerWrapper;
	private GenericClient roomServerWrapper;
	
	public MiddleLayer(int port, String carIp, String flightIp, String roomIp,String customerIp) throws IOException{
		super(port);
		serverResponsibilities = new HashMap<String,String>();
		initializeResponsibilities();
		
		String[] cars = carIp.split(":");
		String[] flights = flightIp.split(":");
		String[] rooms = roomIp.split(":");
		String[] customers = customerIp.split(":");
		
		customerServerWrapper = new GenericClient(customers[0],Integer.parseInt(customers[1]));
		carServerWrapper = new GenericClient(cars[0],Integer.parseInt(cars[1]));
		flightServerWrapper = new GenericClient(flights[0],Integer.parseInt(flights[1]));
		roomServerWrapper = new GenericClient(rooms[0],Integer.parseInt(rooms[1]));
	}
	
	protected void initializeResponsibilities(){
		
		serverResponsibilities.put("addFlight", FLIGHT_SERVER);
		serverResponsibilities.put("addCars", CAR_SERVER);
		serverResponsibilities.put("addRooms", ROOM_SERVER);
		serverResponsibilities.put("newCustomer", CUSTOMER_SERVER);
		serverResponsibilities.put("deleteFlight", FLIGHT_SERVER);
		serverResponsibilities.put("deleteCars", CAR_SERVER);
		serverResponsibilities.put("deleteRooms", ROOM_SERVER);
		serverResponsibilities.put("deleteCustomer", CUSTOMER_SERVER);
		serverResponsibilities.put("queryFlight", FLIGHT_SERVER);
		serverResponsibilities.put("queryCars", CAR_SERVER);
		serverResponsibilities.put("queryRooms", ROOM_SERVER);
		serverResponsibilities.put("queryCustomerInfo", CUSTOMER_SERVER);
		serverResponsibilities.put("queryFlightPrice", FLIGHT_SERVER);
		serverResponsibilities.put("queryCarsPrice", CAR_SERVER);
		serverResponsibilities.put("queryRoomsPrice", ROOM_SERVER);
		serverResponsibilities.put("reserveFlight", FLIGHT_SERVER);
		serverResponsibilities.put("reserveCar", CAR_SERVER);
		serverResponsibilities.put("reserveRoom", ROOM_SERVER);
		serverResponsibilities.put("itinerary", CUSTOMER_SERVER);
	}
	
	protected Reply responsibleServerCall(String methodName,LinkedList<Object> args) {
		String server = serverResponsibilities.get(methodName);
		
		if(server==null){
			System.out.println("Method: " + methodName + " is not implemented");
			return new Reply(Reply.STATUS_METHOD_NOT_FOUND,new LinkedList<Object>());
		}
		
		if(server.equals(CUSTOMER_SERVER)){
			System.out.println("Method: " + methodName + " delegated to Customer server");
			return customerServerWrapper.sendRequest(new Request(methodName,args));
		}
		
		if(server.equals(CAR_SERVER)){
			System.out.println("Method: " + methodName + " delegated to Car server");
			return carServerWrapper.sendRequest(new Request(methodName,args));
		}
		
		if(server.equals(FLIGHT_SERVER)){
			System.out.println("Method: " + methodName + " delegated to Flight server");
			return flightServerWrapper.sendRequest(new Request(methodName,args));
		}
		
		if(server.equals(ROOM_SERVER)){
			System.out.println("Method: " + methodName + " delegated to Room server");
			return roomServerWrapper.sendRequest(new Request(methodName,args));
		}
		
		System.out.println("Method: " + methodName + " is not implemented");
		return new Reply(Reply.STATUS_METHOD_NOT_FOUND,new LinkedList<Object>());
		
	}
	
	@Override
	protected Reply handleMethod(String methodName, LinkedList<Object> args) {
		return responsibleServerCall(methodName,args);
	}
	
	public static void main(String[] args){
		if(args.length!=5){
			System.out.println("Usage: java MiddleLayer middleServerPort customerServerIP:Port carServerIP:port roomServerIP:port flightServerIp:port");
			System.exit(0);
		}
		
		int port = 0;
		
		try{
			port = Integer.parseInt(args[0]);
		} catch(NumberFormatException e){
			System.out.println("Usage: java MiddleLayer middleServerPort customerServerIP:Port carServerIP:port roomServerIP:port flightServerIp:port");
			System.exit(0);
		}
		
		String customerIp = args[1];
		String carIp = args[2];
		String roomIp = args[3];
		String flightIp = args[4];
		
		MiddleLayer middleLayer;
		try {
			middleLayer = new MiddleLayer(port,carIp,flightIp,roomIp,customerIp);
			middleLayer.start();
		} catch (IOException e) {
			System.err.println("The server was unable to start");
			e.printStackTrace();
		}
	}


}
